#include <iostream>

using namespace std;

namespace aoqiang
{
    // aoqiang::unique_ptr<Test> p1(new Test(10));
    template <class T>
    class unique_ptr
    {
    public:
        unique_ptr(T *ptr) : ptr_(ptr)
        {
        }
        ~unique_ptr() = default;

        unique_ptr(unique_ptr<T> &ap) = delete;
        unique_ptr<T> &operator=(unique_ptr<T> &ap) = delete;

        T &operator*()
        {
            return *ptr_;
        }
        T *operator->()
        {
            return ptr_;
        }

    private:
        T *ptr_;
    };

    template <class T>
    class shared_ptr
    {
    public:
        shared_ptr(T *ptr = nullptr) : _ptr(ptr), _count(new int(1))
        {
        }
        ~shared_ptr()
        {
        }
        T &operator*()
        {
            return *ptr_;
        }
        T *operator->()
        {
            return ptr_;
        }
        shared_ptr(const shared_ptr<T> &sp):_ptr(sp._ptr),_count(sp._count)
        {
            ++(*_count);
        }
        shared_ptr<T>& operator=(const shared_ptr<T>& sp)
        {
            if(_ptr == sp._ptr)
            {
                return *this;
            }
            if(--(*_count) == 0)
            {
                delete _ptr;
                delete _count;
            }
            _ptr = sp._ptr;
            _count = sp._count;
            ++(*_count);

            return *this;
        }
        int use_count()const
        {
            return *_count;
        }
        T* get()const
        {
            return _ptr;
        }

    private:
        T *_ptr;
        int *_count;
    };
}
